#include <QtGui>
#include <QtOpenGL/qgl.h>

#include <GL/glut.h>

#include "glchild.h"

QString materialName[MATERIAL_END] =
{
    "Silver",
    "Gold",
    "Jade",
    "Light blue",
    "Emerald",
    "Polished silver",
    "Chrome",
    "Copper",
    "Polished gold",
    "Pewter",
    "Obsidian",
    "Black plastic",
    "Polished bronze",
    "Polished copper",
    "Pearl",
    "Ruby",
    "Turquoise",
    "Brass"
};

GLChild::GLChild()
{
    winWidth = 640;
    winHeiht = 480;
    setGeometry( 0, 0, winWidth, winHeiht );
    setAttribute(Qt::WA_DeleteOnClose);
    isUntitled = true;

    m_FirstView = true;

    leftButtonDown = false;
    rightButtonDown = false;

    lighting = false;
}

GLChild::~GLChild()
{

}

void GLChild::newFile()
{
    static int sequenceNumber = 1;

    isUntitled = true;
    curFile = tr("document%1.txt").arg(sequenceNumber++);
    setWindowTitle(curFile + "[*]");
}

bool GLChild::loadFile(const QString &fileName)
{
    QFile file(fileName);

    QApplication::setOverrideCursor(Qt::WaitCursor);

    const char* str = fileName.toLatin1().data();


    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);

    return true;
}

bool GLChild::save()
{
    QString filter = tr("EPS (*.eps);;PS (*.ps);;TEX (*.tex);;PDF (*.pdf);;SVG (*.svg);;All files (*.*)");
    QString selFilter = tr("EPS (*.eps");
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save"), curFile, filter, &selFilter);

    int opt;
    char ext[32];
    static int format = GL2PS_PS;

    if (fileName.isEmpty())
    {
        return false;
    }

    if (selFilter == "PS (*.ps)")
    {
        format = GL2PS_PS;
    }
    else if (selFilter == "TEX (*.tex)")
    {
        format = GL2PS_TEX;
    }
    else if (selFilter == "PDF (*.pdf)")
    {
        format = GL2PS_PDF;
    }
    else if (selFilter == "SVG (*.svg)")
    {
        format = GL2PS_SVG;
    }
    else
    {
        format = GL2PS_EPS;
    }

    strcpy(ext, gl2psGetFileExtension(format));

    QByteArray ba = (fileName).toLocal8Bit();
    char *path = ba.data();
    // opt = GL2PS_DRAW_BACKGROUND;
    opt = GL2PS_DRAW_BACKGROUND | GL2PS_TIGHT_BOUNDING_BOX ;
    writefile(format, GL2PS_SIMPLE_SORT, opt, 0.5, path, ext);

//    ba = (fileName + "Culled").toLocal8Bit();
//    path = ba.data();
//    opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL;
//    writefile(format, GL2PS_SIMPLE_SORT, opt, 0, path, ext);

//    ba = (fileName + "Shading2").toLocal8Bit();
//    path = ba.data();
//    opt = GL2PS_DRAW_BACKGROUND | GL2PS_NO_PS3_SHADING | GL2PS_TIGHT_BOUNDING_BOX;
//    writefile(format, GL2PS_SIMPLE_SORT, opt, 2, path, ext);

//    ba = (fileName + "Shading8").toLocal8Bit();
//    path = ba.data();
//    writefile(format, GL2PS_SIMPLE_SORT, opt, 8, path, ext);

//    ba = (fileName + "Shading16").toLocal8Bit();
//    path = ba.data();
//    writefile(format, GL2PS_SIMPLE_SORT, opt, 16, path, ext);

//    ba = (fileName + "NoText").toLocal8Bit();
//    path = ba.data();
//    opt = GL2PS_NO_TEXT;
//    writefile(format, GL2PS_SIMPLE_SORT, opt, 0, path, ext);

//    ba = (fileName + "Bsp").toLocal8Bit();
//    path = ba.data();
//    opt = GL2PS_DRAW_BACKGROUND | GL2PS_BEST_ROOT;
//    writefile(format, GL2PS_BSP_SORT, opt, 0, path, ext);

//    ba = (fileName + "BspCulled").toLocal8Bit();
//    path = ba.data();
//    opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT;
//    writefile(format, GL2PS_BSP_SORT, opt, 0, path, ext);

#ifdef GL2PS_HAVE_ZLIB
    ba = (fileName + "BspCulledCompressed").toLocal8Bit();
    path = ba.data();
    opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT | GL2PS_COMPRESS;
    if (format == GL2PS_PS || format == GL2PS_EPS) strcat(ext, ".gz");
    else if (format == GL2PS_SVG) strcat(ext, "z");
    writefile(format, GL2PS_BSP_SORT, opt, 0, path, ext);
#endif

    printf("GL2PS %d.%d.%d%s done with all images\n", GL2PS_MAJOR_VERSION,
           GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION);

    return true;
}

bool GLChild::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
                                                    curFile);
    if (fileName.isEmpty())
        return false;

    return saveFile(fileName);
}

bool GLChild::saveFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, tr("GCS"),
                             tr("Cannot write file %1:\n%2.")
                             .arg(fileName)
                             .arg(file.errorString()));
        return false;
    }

//    QTextStream out(&file);
//    QApplication::setOverrideCursor(Qt::WaitCursor);
//    out << toPlainText();
//    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
    return true;
}

QString GLChild::userFriendlyCurrentFile()
{
    return strippedName(curFile);
}

void GLChild::enableLighting()
{
    lighting = !lighting;
    repaint();
}

void GLChild::closeEvent(QCloseEvent *event)
{
    if (maybeSave()) {
        event->accept();
    } else {
        event->ignore();
    }
}

void GLChild::documentWasModified()
{
    //    setWindowModified(document()->isModified());
}

bool GLChild::maybeSave()
{
//    if (document()->isModified()) {
//    QMessageBox::StandardButton ret;
//        ret = QMessageBox::warning(this, tr("GCS"),
//                     tr("'%1' has been modified.\n"
//                        "Do you want to save your changes?")
//                     .arg(userFriendlyCurrentFile()),
//                     QMessageBox::Save | QMessageBox::Discard
//             | QMessageBox::Cancel);
//        if (ret == QMessageBox::Save)
//            return save();
//        else if (ret == QMessageBox::Cancel)
//            return false;
//    }
    return true;
}

void GLChild::setCurrentFile(const QString &fileName)
{
    curFile = QFileInfo(fileName).canonicalFilePath();
    isUntitled = false;
//    document()->setModified(false);
    setWindowModified(false);
    setWindowTitle(userFriendlyCurrentFile() + "[*]");
}

QString GLChild::strippedName(const QString &fullFileName)
{
    return QFileInfo(fullFileName).fileName();
}

void GLChild::initializeGL()
{
    InitCamera();

    glShadeModel( GL_SMOOTH );

    glClearColor( 1.0, 1.0, 1.0, 0.0 );

    glClearDepth( 1.0 );

    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );

    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

    ChangeMaterial("Gold", false);
    resetView();
}

void GLChild::resizeGL(int w, int h)
{
    if ( h == 0 )
    {
        h = 1;
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    viewport.SetSize(w, h);
    viewport.glDraw();
    camera.glDraw(viewport);
    glDrawBuffer(GL_BACK);
}

void GLChild::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPointSize(2.0);
    gl2psPointSize(2.0);

    if (!lighting)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        gl2psEnable(GL2PS_BLEND);
        gl2psBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        gl2psDisable(GL_LIGHTING);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
    }
    else
    {
        glDisable(GL_BLEND);
        gl2psDisable(GL2PS_BLEND);
        glEnable(GL_DEPTH_TEST);

        float g_lightPos[4] = {10, 10, 10, 1.0f};
        glShadeModel(GL_SMOOTH);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glLightfv(GL_LIGHT0, GL_POSITION, g_lightPos);
        glEnable(GL_NORMALIZE);
        glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    }

    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();

    ViewAll();

    // setup viewpoint from current arcball
    arcball.glDraw();

    glPopMatrix();

    glFlush();
    glFinish();
}

void GLChild::mousePressEvent(QMouseEvent *event)
{
    // grabMouse();

    if (event->buttons() & Qt::LeftButton)
    {
        leftButtonDown = true;
        HandleMouseButton(event->x(), event->y());
    }
    else if (event->buttons() & Qt::RightButton)
    {
        rightButtonDown = true;
        HandleMouseButton(event->x(), event->y());
    }
}

void GLChild::mouseMoveEvent(QMouseEvent *event)
{
    if(leftButtonDown || rightButtonDown)
    {
        CVector3d vec = arcball.Intersect(event->x(), viewport.yRes() - event->y(),
            camera,viewport);
        arcball.Motion(vec);
        repaint();
    }
}

void GLChild::mouseReleaseEvent(QMouseEvent *event)
{
    // releaseMouse();

    if (event->button() == Qt::LeftButton)
    {
        leftButtonDown = false;
        HandleMouseButton(event->x(), event->y());
    }
    if (event->button() == Qt::RightButton)
    {
        rightButtonDown = false;
        HandleMouseButton(event->x(), event->y());

        repaint();
    }
}

void GLChild::wheelEvent(QWheelEvent *event)
{
    double delta = event->delta()/60;   //delta()一般返回 +-120

    CVector3d vec = CVector3d(0.0, 0.0, 0.0);
    arcball.SetMode(ARCBALL_TRANSLATE_Z);
    arcball.BeginDrag(vec);
    vec.y(vec.y() + delta);
    arcball.Motion(vec);
    arcball.EndDrag(vec);
    repaint();
}

void GLChild::resetView()
{
    arcball.Clear();

    arcball.SetCenter(0, 0, 0);

    ViewAll(false);

    repaint();
}

void GLChild::InitCamera()
{
    // set viewport and camera
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    QRect rect = this->geometry();
    viewport.SetOrigin(0,0);
    viewport.SetSize(rect.width(), rect.height());
    camera.SetHeightAngle(45);
    camera.SetPosition(0., 0., 10.);
    camera.SetOrientation(0.,1.,0.,0);
    camera.SetNearDistance(.1);
    camera.SetFarDistance(100.);
    viewport.glDraw();
    camera.glDraw(viewport);
    glDrawBuffer(GL_BACK);
}

void GLChild::ViewAll(bool check_first)
{
    // make it only once
    if(!m_FirstView && check_first)
        return;

    m_FirstView = false;

    // set up the camera to visualize the whole object
//	TRACE("setup camera.");

    CMatrix44 ArcballMatrix = arcball.GetMatrix();

    CVector3d minBound, maxBound;
    minBound.Set(-20, -20, -20);
    maxBound.Set(20, 20, 20);
    minBound = ArcballMatrix * minBound;
    maxBound = ArcballMatrix * maxBound;
    camera.ViewAll(minBound[0],
        maxBound[0],
        minBound[1],
        maxBound[1],
        minBound[2],
        maxBound[2],
        viewport);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    camera.glDraw(viewport);
    glMatrixMode(GL_MODELVIEW);
}

void GLChild::HandleMouseButton(double x, double y)
{
    CVector3d vec = arcball.Intersect(x, viewport.yRes()-y,
        camera, viewport);
    arcball.EndDrag(vec);
    arcball.SetMode(leftButtonDown + 2*rightButtonDown);
    vec = arcball.Intersect(x, viewport.yRes()-y, camera,viewport);
    arcball.BeginDrag(vec);
}

void GLChild::writefile(int format, int sort, int options, int nbcol,
               const char *filename, const char *extension)
{
  FILE *fp;
  char file[256];
  int state = GL2PS_OVERFLOW, buffsize = 0;
  GLint vp[4];

  strcpy(file, filename);
  strcat(file, ".");
  strcat(file, extension);

  vp[0] = 0;
  vp[1] = 0;
  vp[2] = viewport.Width();
  vp[3] = viewport.Height();

  fp = fopen(file, "wb");

  if(!fp){
    printf("Unable to open file %s for writing\n", file);
    exit(1);
  }

  printf("Saving image to file %s... ", file);
  fflush(stdout);

  while(state == GL2PS_OVERFLOW){
    buffsize += 1024*1024;
    gl2psBeginPage(file, "GCS", vp, format, sort, options,
                   GL_RGBA, 0, NULL, nbcol, nbcol, nbcol,
                   buffsize, fp, file);
    for (int i = 0; i < 3; i++)
    {
        paintGL();
    }
    state = gl2psEndPage();
  }

  fclose(fp);

  printf("Done!\n");
  fflush(stdout);
}

void GLChild::OnMaterials(int nID)
{
    switch(nID)
    {
    case MATERIAL_SILVER:
        ChangeMaterial(QString("Silver"),false);
        repaint();
        break;

    case MATERIAL_GOLD:
        ChangeMaterial(QString("Gold"),false);
        repaint();
        break;

    case MATERIAL_JADE:
        ChangeMaterial(QString("Jade"),false);
        repaint();
        break;

    case MATERIAL_LIGHTBLUE:
        ChangeMaterial(QString("Light blue"),false);
        repaint();
        break;

    case MATERIAL_EMERALD:
        ChangeMaterial(QString("Emerald"),false);
        repaint();
        break;

    case MATERIAL_POLISHEDSILVER:
        ChangeMaterial(QString("Polished silver"),false);
        repaint();
        break;

    case MATERIAL_CHROME:
        ChangeMaterial(QString("Chrome"),false);
        repaint();
        break;

    case MATERIAL_COPPER:
        ChangeMaterial(QString("Copper"),false);
        repaint();
        break;

    case MATERIAL_POLISHEDGOLD:
        ChangeMaterial(QString("Polished gold"),false);
        repaint();
        break;

    case MATERIAL_PEWTER:
        ChangeMaterial(QString("Pewter"),false);
        repaint();
        break;

    case MATERIAL_OBSIDIAN:
        ChangeMaterial(QString("Obsidian"),false);
        repaint();
        break;

    case MATERIAL_BLACKPLASTIC:
        ChangeMaterial(QString("Black plastic"),false);
        repaint();
        break;

    case MATERIAL_POLISHEDBRONZE:
        ChangeMaterial(QString("Polished bronze"),false);
        repaint();
        break;

    case MATERIAL_POLISHEDCOPPER:
        ChangeMaterial(QString("Polished copper"),false);
        repaint();
        break;

    case MATERIAL_PEARL:
        ChangeMaterial(QString("Pearl"),false);
        repaint();
        break;

    case MATERIAL_RUBY:
        ChangeMaterial(QString("Ruby"),false);
        repaint();
        break;

    case MATERIAL_TURQUOISE:
        ChangeMaterial(QString("Turquoise"),false);
        repaint();
        break;

    case MATERIAL_BRASS:
        ChangeMaterial(QString("Brass"),false);
        repaint();
        break;
    }
}

void GLChild::ChangeMaterial(QString str,
                               bool update)
{
    float	ambient[]  = {0.0f,0.0f,0.0f,1.0f};
    float	diffuse[]  = {0.0f,0.0f,0.0f,1.0f};
    float	specular[]  = {0.0f,0.0f,0.0f,1.0f};
    float	emission[]  = {0.3f,0.3f,0.3f,1.0f};
    float shininess[] = {0.0f};

    // Change
    if(str == "Silver")
    {
        // Ambient
        ambient[0] = 0.19225f;
        ambient[1] = 0.19225f;
        ambient[2] = 0.19225f;
        ambient[3] = 1.0f;
        // Diffuse
        diffuse[0] = 0.50754f;
        diffuse[1] = 0.50754f;
        diffuse[2] = 0.50754f;
        diffuse[3] = 1.0f;
        // Specular
        specular[0] = 0.508273f;
        specular[1] = 0.508273f;
        specular[2] = 0.508273f;
        specular[3] = 1.0f;
        // Shininess
        shininess[0] = 51.2f;
    }

    else

    // Change
    if(str == "Gold")
    {
        // Ambient
        ambient[0] = 0.24725f;
        ambient[1] = 0.1995f;
        ambient[2] = 0.0745f;
        ambient[3] = 1.0f;
        // Diffuse
        diffuse[0] = 0.75164f;
        diffuse[1] = 0.60648f;
        diffuse[2] = 0.22648f;
        diffuse[3] = 1.0f;
        // Specular
        specular[0] = 0.928281f;
        specular[1] = 0.855802f;
        specular[2] = 0.666065f;
        specular[3] = 1.0f;
        // Shininess
        shininess[0] = 51.2f;
    }

    else
        // Change
        if(str == "Jade")
        {
            // Ambient
            ambient[0] = 0.135f;
            ambient[1] = 0.2225f;
            ambient[2] = 0.1575f;
            ambient[3] = 0.95f;
            // Diffuse
            diffuse[0] = 0.54f;
            diffuse[1] = 0.89f;
            diffuse[2] = 0.63f;
            diffuse[3] = 0.95f;
            // Specular
            specular[0] = 0.316228f;
            specular[1] = 0.316228f;
            specular[2] = 0.316228f;
            specular[3] = 0.95f;
            // Shininess
            shininess[0] = 12.8f;
        }
        else
            // Change
            if(str == "Light blue")
            {
                // Ambient
                ambient[0] = 0.0f;
                ambient[1] = 0.5f;
                ambient[2] = 0.75f;
                ambient[3] = 1.0f;
                // Diffuse
                diffuse[0] = 0.0f;
                diffuse[1] = 0.5f;
                diffuse[2] = 1.0f;
                diffuse[3] = 1.0f;
                // Specular
                specular[0] = 0.75f;
                specular[1] = 0.75f;
                specular[2] = 0.75f;
                specular[3] = 1.0f;
                // Shininess
                shininess[0] = 64.0f;
            }
            else
                // Change
                if(str == "Emerald")
                {
                    // Ambient
                    ambient[0] = 0.0215f;
                    ambient[1] = 0.1745f;
                    ambient[2] = 0.0215f;
                    ambient[3] = 0.55f;
                    // Diffuse
                    diffuse[0] = 0.07568f;
                    diffuse[1] = 0.61424f;
                    diffuse[2] = 0.07568f;
                    diffuse[3] = 0.55f;
                    // Specular
                    specular[0] = 0.633f;
                    specular[1] = 0.727811f;
                    specular[2] = 0.633f;
                    specular[3] = 0.55f;
                    // Shininess
                    shininess[0] = 76.8f;
                }
                else
                    // Change
                    if(str == "Polished silver")
                    {
                        // Ambient
                        ambient[0] = 0.23125f;
                        ambient[1] = 0.23125f;
                        ambient[2] = 0.23125f;
                        ambient[3] = 1.0f;
                        // Diffuse
                        diffuse[0] = 0.2775f;
                        diffuse[1] = 0.2775f;
                        diffuse[2] = 0.2775f;
                        diffuse[3] = 1.0f;
                        // Specular
                        specular[0] = 0.773911f;
                        specular[1] = 0.773911f;
                        specular[2] = 0.773911f;
                        specular[3] = 1.0f;
                        // Shininess
                        shininess[0] = 89.6f;
                    }
                    else
                        // Change
                        if(str == "Chrome")
                        {
                            // Ambient
                            ambient[0] = 0.25f;
                            ambient[1] = 0.25f;
                            ambient[2] = 0.25f;
                            ambient[3] = 1.0f;
                            // Diffuse
                            diffuse[0] = 0.4f;
                            diffuse[1] = 0.4f;
                            diffuse[2] = 0.4f;
                            diffuse[3] = 1.0f;
                            // Specular
                            specular[0] = 0.774597f;
                            specular[1] = 0.774597f;
                            specular[2] = 0.774597f;
                            specular[3] = 1.0f;
                            // Shininess
                            shininess[0] = 76.8f;
                        }
                        else
                            // Change
                            if(str == "Copper")
                            {
                                // Ambient
                                ambient[0] = 0.19125f;
                                ambient[1] = 0.0735f;
                                ambient[2] = 0.0225f;
                                ambient[3] = 1.0f;
                                // Diffuse
                                diffuse[0] = 0.7038f;
                                diffuse[1] = 0.27048f;
                                diffuse[2] = 0.0828f;
                                diffuse[3] = 1.0f;
                                // Specular
                                specular[0] = 0.256777f;
                                specular[1] = 0.137622f;
                                specular[2] = 0.086014f;
                                specular[3] = 1.0f;
                                // Shininess
                                shininess[0] = 12.8f;
                            }
                            else
                                // Change
                                if(str == "Polished gold")
                                {
                                    // Ambient
                                    ambient[0] = 0.24725f;
                                    ambient[1] = 0.2245f;
                                    ambient[2] = 0.0645f;
                                    ambient[3] = 1.0f;
                                    // Diffuse
                                    diffuse[0] = 0.34615f;
                                    diffuse[1] = 0.3143f;
                                    diffuse[2] = 0.0903f;
                                    diffuse[3] = 1.0f;
                                    // Specular
                                    specular[0] = 0.797357f;
                                    specular[1] = 0.723991f;
                                    specular[2] = 0.208006f;
                                    specular[3] = 1.0f;
                                    // Shininess
                                    shininess[0] = 83.2f;
                                }
                                else
                                    // Change
                                    if(str == "Pewter")
                                    {
                                        // Ambient
                                        ambient[0] = 0.105882f;
                                        ambient[1] = 0.058824f;
                                        ambient[2] = 0.113725f;
                                        ambient[3] = 1.0f;
                                        // Diffuse
                                        diffuse[0] = 0.427451f;
                                        diffuse[1] = 0.470588f;
                                        diffuse[2] = 0.541176f;
                                        diffuse[3] = 1.0f;
                                        // Specular
                                        specular[0] = 0.333333f;
                                        specular[1] = 0.333333f;
                                        specular[2] = 0.521569f;
                                        specular[3] = 1.0f;
                                        // Shininess
                                        shininess[0] = 9.84615f;
                                    }
                                    else
                                        // Change
                                        if(str == "Obsidian")
                                        {
                                            // Ambient
                                            ambient[0] = 0.05375f;
                                            ambient[1] = 0.05f;
                                            ambient[2] = 0.06625f;
                                            ambient[3] = 0.82f;
                                            // Diffuse
                                            diffuse[0] = 0.18275f;
                                            diffuse[1] = 0.17f;
                                            diffuse[2] = 0.22525f;
                                            diffuse[3] = 0.82f;
                                            // Specular
                                            specular[0] = 0.332741f;
                                            specular[1] = 0.328634f;
                                            specular[2] = 0.346435f;
                                            specular[3] = 0.82f;
                                            // Shininess
                                            shininess[0] = 38.4f;
                                        }
                                        else
                                            // Change
                                            if(str == "Black plastic")
                                            {
                                                // Ambient
                                                ambient[0] = 0.0f;
                                                ambient[1] = 0.0f;
                                                ambient[2] = 0.0f;
                                                ambient[3] = 1.0f;
                                                // Diffuse
                                                diffuse[0] = 0.01f;
                                                diffuse[1] = 0.01f;
                                                diffuse[2] = 0.01f;
                                                diffuse[3] = 1.0f;
                                                // Specular
                                                specular[0] = 0.5f;
                                                specular[1] = 0.5f;
                                                specular[2] = 0.5f;
                                                specular[3] = 1.0f;
                                                // Shininess
                                                shininess[0] = 32.0f;
                                            }

                                            else
                                                // Change
                                                if(str == "Polished bronze")
                                                {
                                                    // Ambient
                                                    ambient[0] = 0.25f;
                                                    ambient[1] = 0.148f;
                                                    ambient[2] = 0.006475f;
                                                    ambient[3] = 1.0f;
                                                    // Diffuse
                                                    diffuse[0] = 0.4f;
                                                    diffuse[1] = 0.2368f;
                                                    diffuse[2] = 0.1036f;
                                                    diffuse[3] = 1.0f;
                                                    // Specular
                                                    specular[0] = 0.774597f;
                                                    specular[1] = 0.458561f;
                                                    specular[2] = 0.200621f;
                                                    specular[3] = 1.0f;
                                                    // Shininess
                                                    shininess[0] = 76.8f;
                                                }
                                                else
                                                    // Change
                                                    if(str == "Polished copper")
                                                    {
                                                        // Ambient
                                                        ambient[0] = 0.2295f;
                                                        ambient[1] = 0.08825f;
                                                        ambient[2] = 0.0275f;
                                                        ambient[3] = 1.0f;
                                                        // Diffuse
                                                        diffuse[0] = 0.5508f;
                                                        diffuse[1] = 0.2118f;
                                                        diffuse[2] = 0.066f;
                                                        diffuse[3] = 1.0f;
                                                        // Specular
                                                        specular[0] = 0.580594f;
                                                        specular[1] = 0.223257f;
                                                        specular[2] = 0.0695701f;
                                                        specular[3] = 1.0f;
                                                        // Shininess
                                                        shininess[0] = 51.2f;
                                                    }
                                                    else
                                                        // Change
                                                        if(str == "Pearl")
                                                        {
                                                            // Ambient
                                                            ambient[0] = 0.25f;
                                                            ambient[1] = 0.20725f;
                                                            ambient[2] = 0.20725f;
                                                            ambient[3] = 0.922f;
                                                            // Diffuse
                                                            diffuse[0] = 1.0f;
                                                            diffuse[1] = 0.829f;
                                                            diffuse[2] = 0.829f;
                                                            diffuse[3] = 0.922f;
                                                            // Specular
                                                            specular[0] = 0.296648f;
                                                            specular[1] = 0.296648f;
                                                            specular[2] = 0.296648f;
                                                            specular[3] = 0.922f;
                                                            // Shininess
                                                            shininess[0] = 11.264f;
                                                        }
                                                        else
                                                            // Change
                                                            if(str == "Ruby")
                                                            {
                                                                // Ambient
                                                                ambient[0] = 0.1745f;
                                                                ambient[1] = 0.01175f;
                                                                ambient[2] = 0.01175f;
                                                                ambient[3] = 0.55f;
                                                                // Diffuse
                                                                diffuse[0] = 0.61424f;
                                                                diffuse[1] = 0.04136f;
                                                                diffuse[2] = 0.04136f;
                                                                diffuse[3] = 0.55f;
                                                                // Specular
                                                                specular[0] = 0.727811f;
                                                                specular[1] = 0.626959f;
                                                                specular[2] = 0.626959f;
                                                                specular[3] = 0.55f;
                                                                // Shininess
                                                                shininess[0] = 76.8f;
                                                            }
                                                        else
                                                            // Change
                                                            if(str == "Turquoise")
                                                            {
                                                                // Ambient
                                                                ambient[0] = 0.1f;
                                                                ambient[1] = 0.18725f;
                                                                ambient[2] = 0.1745f;
                                                                ambient[3] = 0.8f;
                                                                // Diffuse
                                                                diffuse[0] = 0.396f;
                                                                diffuse[1] = 0.74151f;
                                                                diffuse[2] = 0.69102f;
                                                                diffuse[3] = 0.8f;
                                                                // Specular
                                                                specular[0] = 0.297254f;
                                                                specular[1] = 0.30829f;
                                                                specular[2] = 0.306678f;
                                                                specular[3] = 0.8f;
                                                                // Shininess
                                                                shininess[0] = 12.8f;
                                                            }
                                                        else
                                                            // Change
                                                            if(str == "Brass")
                                                            {
                                                                // Ambient
                                                                ambient[0] = 0.329412f;
                                                                ambient[1] = 0.223529f;
                                                                ambient[2] = 0.027451f;
                                                                ambient[3] = 1.0f;
                                                                // Diffuse
                                                                diffuse[0] = 0.780392f;
                                                                diffuse[1] = 0.268627f;
                                                                diffuse[2] = 0.113725f;
                                                                diffuse[3] = 1.0f;
                                                                // Specular
                                                                specular[0] = 0.992157f;
                                                                specular[1] = 0.741176f;
                                                                specular[2] = 0.807843f;
                                                                specular[3] = 1.0f;
                                                                // Shininess
                                                                shininess[0] = 27.8974f;
                                                            }

    // apply
//	glMaterialfv( GL_FRONT, GL_AMBIENT,   ambient);
//	glMaterialfv( GL_FRONT, GL_DIFFUSE,   diffuse);
//	glMaterialfv( GL_FRONT, GL_SPECULAR,  specular);
//	glMaterialfv( GL_FRONT, GL_SHININESS, shininess);
//	glMaterialfv( GL_FRONT, GL_EMISSION,  emission);

    glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,   ambient);
    glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE,   diffuse);
    glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,  specular);
    glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess);
    glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION,  emission);

    if(update)
        repaint();
}
